import pickle
from collections.abc import Sequence


def save_variable(v,filename):
    f = open(filename, 'wb')
    pickle.dump(v, f)
    f.close()
    return filename


def load_variable(filename):
    f = open(filename, 'rb')
    r = pickle.load(f)
    f.close()
    return r


def merged_ordered(sequence_a, sequence_b, key=None):

    if key is None:
        def default_key(x):
            return x
        key = default_key
    merged = []
    i, j = 0, 0
    while i < len(sequence_a) and j < len(sequence_b):
        if key(sequence_a[i]) <= key(sequence_b[j]):
            merged.append(sequence_a[i])
            i += 1
        else:
            merged.append(sequence_b[j])
            j += 1
    if i == len(sequence_a):
        while j < len(sequence_b):
            merged.append(sequence_b[j])
            j += 1
    else:
        while i < len(sequence_a):
            merged.append(sequence_a[i])
            i += 1
    return merged


def brief(sequence: Sequence, ends_len: int = 3) -> str:
    """
    Return the brief content of a sequence, with elements in the middle part omitted.

    :param sequence: input sequence
    :param ends_len: a integer representing the number of elements to keep at the head and tail
    :return: a str representing the brief content of the sequence
    """

    # if the sequence is too short
    if len(sequence) <= ends_len * 2:
        return str(sequence)

    # if the sequence is a range instance, convert it to str and return since it's inherently brief
    if isinstance(sequence, range):
        return str(sequence)

    # if the sequence is a str
    if isinstance(sequence, str):
        return sequence[:ends_len] + ' ... ' + sequence[-ends_len:]

    # otherwise, e.g. a list, a tuple
    head, tail = str(sequence[:ends_len]), str(sequence[-ends_len:])
    if head.endswith((')', ']', '}')):
        head = head[:-1]
    if tail.startswith(('(', '[', '{')):
        tail = tail[1:]
    return head + ', ..., ' + tail
